﻿using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using xzz.webapi.CustomActionFilters;
using xzz.webapi.Data;
using xzz.webapi.Models.Domain;
using xzz.webapi.Models.DTO;
using xzz.webapi.Repository;

namespace xzz.webapi.Controllers
{
    //http://localhost:prornumner/api/regions
    [Route("api/[controller]")]
    [ApiController]
    public class RegionsController : ControllerBase
    {
        #region Repository查询

        private readonly IRegionRepository regionRepository;
        private readonly IMapper mapper;

        public RegionsController(IRegionRepository RegionRepository, IMapper mapper)
        {
            regionRepository = RegionRepository;
            this.mapper = mapper;
        }

        //http://localhost:prornumner/api/regions
        [HttpGet]
        public async Task<IActionResult> GetAll()
        {
            var regionsDomain = await regionRepository.GetAllAsync();
            //Models to DTO
            /*var regionsDto = new List<RegionDto>();
            foreach (var item in regionsDomain)
            {
                regionsDto.Add(
                    new RegionDto()
                    {
                        Id = item.Id,
                        Name = item.Name,
                        Code = item.Code,
                        RegionIMageUrl = item.RegionIMageUrl,
                    }
                    );
            }*/
            //use AutoMapper Models to DTO
            var regionsDto = mapper.Map<List<RegionDto>>(regionsDomain);
            return Ok(regionsDto);
        }

        [HttpGet]
        [Route("{id:Guid}")]
        public async Task<IActionResult> GetById([FromRoute] Guid id)
        {
            //Map Domain Models to DTOS
            var regionsDomain = await regionRepository.GetByIdAsync(id);
            if (regionsDomain == null)
            {
                return NotFound();
            }
            //var regionsDto = new RegionDto()
            //{
            //    Id = regionsDomain.Id,
            //    Name = regionsDomain.Name,
            //    Code = regionsDomain.Code,
            //    RegionIMageUrl = regionsDomain.RegionIMageUrl,
            //};
            var regionsDto = mapper.Map<RegionDto>(regionsDomain);
            return Ok(regionsDto);
        }

        [HttpPost]
        [ValidateModel]
        public async Task<IActionResult> Create([FromBody] AddRegionRequestDto addRegionRequestDto)
        {
            //2、ValidateModel => Custom Validate Model Attribute（自定义）
            //1、Model判断
            //if (ModelState.IsValid)
            //{
            //Map or Convert DTO to Domain Model
            //var regionsDomainModel = new Region
            //{
            //    Name = addRegionRequestDto.Name,
            //    Code = addRegionRequestDto.Code,
            //    RegionIMageUrl = addRegionRequestDto.RegionIMageUrl,
            //};
            var regionsDomainModel = mapper.Map<Region>(addRegionRequestDto);
            //Use Domain Model to create Region
            regionsDomainModel = await regionRepository.CreateAsync(regionsDomainModel);
            //Map or Domain Model back to DTO
            //var regionsDto = new RegionDto
            //{
            //    Id = regionsDomainModel.Id,
            //    Name = regionsDomainModel.Name,
            //    Code = regionsDomainModel.Code,
            //    RegionIMageUrl = regionsDomainModel.RegionIMageUrl,
            //};
            var regionsDto = mapper.Map<RegionDto>(regionsDomainModel);
            return CreatedAtAction(nameof(GetById), new { id = regionsDto.Id }, regionsDto);
            //}
            //else
            //{
            //    return BadRequest(ModelState);
            //}
        }

        [HttpPut]
        [Route("{id:Guid}")]
        public async Task<IActionResult> Update([FromRoute] Guid id, [FromBody] UpdateRegionRequestDto updateRegionRequestDto)
        {
            //Dto to model
            //var regionsDomainModel = new Region
            //{
            //    Name = updateRegionRequestDto.Name,
            //    Code = updateRegionRequestDto.Code,
            //    RegionIMageUrl = updateRegionRequestDto.RegionIMageUrl,
            //};
            var regionsDomainModel = mapper.Map<Region>(updateRegionRequestDto);
            regionsDomainModel = await regionRepository.UpdateAsync(id, regionsDomainModel);
            if (regionsDomainModel == null)
            {
                return NotFound();
            }
            //Map or Domain Model back to DTO
            //var regionsDto = new RegionDto
            //{
            //    Id = regionsDomainModel.Id,
            //    Name = regionsDomainModel.Name,
            //    Code = regionsDomainModel.Code,
            //    RegionIMageUrl = regionsDomainModel.RegionIMageUrl,
            //};
            var regionsDto = mapper.Map<RegionDto>(regionsDomainModel);
            return Ok(regionsDto);
        }

        [HttpDelete]
        [Route("{id:Guid}")]
        public async Task<IActionResult> Delete([FromRoute] Guid id)
        {
            var regionsDomainModel = await regionRepository.DeleteAsync(id);
            if (regionsDomainModel == null)
            {
                return NotFound();
            }
            //Map or Domain Model back to DTO
            //var regionsDto = new RegionDto
            //{
            //    Id = regionsDomainModel.Id,
            //    Name = regionsDomainModel.Name,
            //    Code = regionsDomainModel.Code,
            //    RegionIMageUrl = regionsDomainModel.RegionIMageUrl,
            //};
            var regionsDto = mapper.Map<RegionDto>(regionsDomainModel);
            return Ok(regionsDto);
        }

        #endregion

        #region dbContext查询
        //private readonly MYDbContext dbContext;

        //public RegionsController(MYDbContext dbContext)
        //{
        //    this.dbContext = dbContext;
        //}

        ////http://localhost:prornumner/api/regions
        //[HttpGet]
        //public async Task<IActionResult> GetAll()
        //{
        //    //Get Data From Database => Domain models
        //    //var regions = dbContext.Regions.ToList();
        //    //return Ok(regions);

        //    //Map Domain Models to DTOS
        //    //传统
        //    //var regionsDomain = dbContext.Regions.ToList();
        //    //异步
        //    var regionsDomain = await dbContext.Regions.ToListAsync()
        //    var regionsDto = new List<RegionDto>();
        //    foreach (var item in regionsDomain)
        //    {
        //        regionsDto.Add(
        //            new RegionDto()
        //            {
        //                Id = item.Id,
        //                Name = item.Name,
        //                Code = item.Code,
        //                RegionIMageUrl = item.RegionIMageUrl,
        //            }
        //            );
        //    }
        //    return Ok(regionsDto);
        //    /*            var regions = new List<Region>
        //                    {
        //                        new Region{
        //                            Id=Guid.NewGuid(),
        //                            Name="regions",
        //                            Code="1",
        //                            RegionIMageUrl="http://ww.com/1.png"
        //                        },
        //                        new Region{
        //                            Id=Guid.NewGuid(),
        //                            Name="regions1",
        //                            Code="11",
        //                            RegionIMageUrl="http://ww.com/11.png"
        //                        },
        //                        new Region{
        //                            Id=Guid.NewGuid(),
        //                            Name="regions1",
        //                            Code="111",
        //                            RegionIMageUrl="http://ww.com/111.png"
        //                        }
        //                                        };*/
        //    //return Ok(regions);
        //}

        //[HttpGet]
        //[Route("{id:Guid}")]
        //public async Task<IActionResult> GetById([FromRoute] Guid id)
        //{
        //    //Get Data From Database => Domain models
        //    //var regions = dbContext.Regions.Find(id);
        //    //var regions = dbContext.Regions.FirstOrDefault(x => x.Id == id);
        //    //if (regions == null)
        //    //{
        //    //    return NotFound();
        //    //}
        //    //return Ok(regions);
        //    //Map Domain Models to DTOS
        //    var regionsDomain = await dbContext.Regions.FirstOrDefaultAsync(x => x.Id == id);
        //    if (regionsDomain == null)
        //    {
        //        return NotFound();
        //    }
        //    var regionsDto = new RegionDto()
        //    {
        //        Id = regionsDomain.Id,
        //        Name = regionsDomain.Name,
        //        Code = regionsDomain.Code,
        //        RegionIMageUrl = regionsDomain.RegionIMageUrl,
        //    };
        //    return Ok(regionsDto);
        //}

        //[HttpPost]
        //public async Task<IActionResult> Create([FromBody] AddRegionRequestDto addRegionRequestDto)
        //{
        //    //Map or Convert DTO to Domain Model
        //    var regionsDomainModel = new Region
        //    {
        //        Name = addRegionRequestDto.Name,
        //        Code = addRegionRequestDto.Code,
        //        RegionIMageUrl = addRegionRequestDto.RegionIMageUrl,
        //    };
        //    //Use Domain Model to create Region
        //    await dbContext.Regions.AddAsync(regionsDomainModel);
        //    await dbContext.SaveChangesAsync();
        //    //Map or Domain Model back to DTO
        //    var regionsDto = new RegionDto
        //    {
        //        Id = regionsDomainModel.Id,
        //        Name = regionsDomainModel.Name,
        //        Code = regionsDomainModel.Code,
        //        RegionIMageUrl = regionsDomainModel.RegionIMageUrl,
        //    };
        //    return CreatedAtAction(nameof(GetById), new { id = regionsDto.Id }, regionsDto);
        //}

        //[HttpPost]
        //[Route("{id:Guid}")]
        //public async Task<IActionResult> Update([FromRoute] Guid id, [FromBody] UpdateRegionRequestDto updateRegionRequestDto)
        //{
        //    var regionsDomainModel = dbContext.Regions.FirstOrDefault(x => x.Id == id);
        //    if (regionsDomainModel == null)
        //    {
        //        return NotFound();
        //    }
        //    //Dto to model
        //    regionsDomainModel.Code = updateRegionRequestDto.Code;
        //    regionsDomainModel.Name = updateRegionRequestDto.Name;
        //    regionsDomainModel.RegionIMageUrl = updateRegionRequestDto.RegionIMageUrl;
        //    await dbContext.SaveChangesAsync();
        //    //Map or Domain Model back to DTO
        //    var regionsDto = new RegionDto
        //    {
        //        Id = regionsDomainModel.Id,
        //        Name = regionsDomainModel.Name,
        //        Code = regionsDomainModel.Code,
        //        RegionIMageUrl = regionsDomainModel.RegionIMageUrl,
        //    };
        //    return Ok(regionsDto);
        //}

        //[HttpDelete]
        //[Route("{id:Guid}")]
        //public async Task<IActionResult> Delete([FromRoute] Guid id)
        //{
        //    var regionsDomainModel = await dbContext.Regions.FirstOrDefaultAsync(x => x.Id == id);
        //    if (regionsDomainModel == null)
        //    {
        //        return NotFound();
        //    }
        //    dbContext.Regions.Remove(regionsDomainModel);
        //    await dbContext.SaveChangesAsync();
        //    //Map or Domain Model back to DTO
        //    var regionsDto = new RegionDto
        //    {
        //        Id = regionsDomainModel.Id,
        //        Name = regionsDomainModel.Name,
        //        Code = regionsDomainModel.Code,
        //        RegionIMageUrl = regionsDomainModel.RegionIMageUrl,
        //    };
        //    return Ok(regionsDto);
        //}
        #endregion
    }
}
